home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / p4 / p4-1_2b.lha / p4-1.2b / lib / p4_utils.c < prev    next >
C/C++ Source or Header  |  1993-02-23  |  16KB  |  660 lines

  1. #include "p4.h"
  2. #include "p4_sys.h"
  3.  
  4. char *p4_version()
  5. {
  6.     return(P4_PATCHLEVEL);
  7. }
  8.  
  9. char *p4_machine_type()
  10. {
  11.     return(P4_MACHINE_TYPE);
  12. }
  13.  
  14.  
  15. int p4_initenv(argc, argv)
  16. int *argc;
  17. char **argv;
  18. {
  19.     int i, rc;
  20.     P4BOOL am_slave = FALSE;
  21.  
  22.     sprintf(whoami_p4, "xm_%d", getpid());
  23.  
  24.     for (i = 0; i < *argc; i++)
  25.     if (strcmp(argv[i], "-amp4slave") == 0)
  26.         am_slave = TRUE;
  27.  
  28. #   if defined(IPSC860) || defined(CM5) || defined(NCUBE)
  29.     if (MYNODE() != 0)
  30.         am_slave = TRUE;
  31. #    endif
  32.  
  33. #   if defined(CM5)
  34.     CMMD_fset_io_mode( stdin,  CMMD_independent );
  35.     CMMD_fset_io_mode( stdout, CMMD_independent );
  36.     CMMD_fset_io_mode( stderr, CMMD_independent );
  37. #   endif
  38.  
  39.     p4_local  = NULL;
  40.     p4_global = NULL;
  41.  
  42.     if (am_slave)
  43.     {
  44. #       if defined(IPSC860)  ||  defined(CM5)  ||  defined(NCUBE)
  45.         if (MYNODE() == 0)
  46.     {
  47. #           if defined(IPSC860_SOCKETS)  ||  defined(CM5_SOCKETS)  ||  defined(NCUBE_SOCKETS)
  48.         rc = rm_start(argc, argv);
  49. #           endif
  50.     }
  51.     else
  52.     {
  53.         rc = ns_start(argc, argv);
  54.     }
  55. #       else
  56.     rc = rm_start(argc, argv);
  57. #       endif
  58.     ALOG_SETUP(p4_local->my_id,ALOG_TRUNCATE);
  59.     }
  60.     else
  61.     {
  62.     rc = bm_start(argc, argv);
  63.         ALOG_MASTER(0,ALOG_TRUNCATE);
  64.         ALOG_DEFINE(BEGIN_USER,"beg_user","");
  65.         ALOG_DEFINE(END_USER,"end_user","");
  66.         ALOG_DEFINE(BEGIN_SEND,"beg_send","");
  67.         ALOG_DEFINE(END_SEND,"end_send","");
  68.         ALOG_DEFINE(BEGIN_RECV,"beg_recv","");
  69.         ALOG_DEFINE(END_RECV,"end_recv","");
  70.         ALOG_DEFINE(BEGIN_WAIT,"beg_wait","");
  71.         ALOG_DEFINE(END_WAIT,"end_wait","");
  72.     }
  73.     ALOG_LOG(p4_local->my_id,BEGIN_USER,0,"");
  74.     return (rc);
  75. }
  76.  
  77. char *p4_shmalloc(n)
  78. int n;
  79. {
  80.     char *rc;
  81.  
  82.     if ((rc = MD_shmalloc(n)) == NULL)
  83.     p4_dprintf("p4_shmalloc returning NULL; request = %d bytes\n",n);
  84.     return (rc);
  85. }
  86.  
  87. P4VOID p4_shfree(p)
  88. char *p;
  89. {
  90.     MD_shfree(p);
  91. }
  92.  
  93. int p4_num_cluster_ids()
  94. {
  95.     return (p4_global->local_slave_count + 1);
  96. }
  97.  
  98. int p4_num_total_ids()
  99. {
  100.     return (p4_global->num_in_proctable);
  101. }
  102.  
  103. int p4_num_total_slaves()
  104. {
  105.     return (p4_global->num_in_proctable - 1);
  106. }
  107.  
  108.  
  109. P4VOID p4_global_barrier(type)
  110. int type;
  111. {
  112.     int dummy[1];
  113.  
  114.      p4_global_op(type, (char *) dummy, 1, sizeof(int), p4_int_sum_op, P4INT);
  115. }
  116.  
  117.  
  118. P4VOID p4_get_cluster_masters(numids, ids)
  119. int *numids, ids[];
  120. {
  121.     int node;
  122.  
  123.     ids[0] = 0;
  124.     *numids = 1;
  125.     for (node = 1; node < p4_global->num_in_proctable; node++)
  126.     {
  127.     if (p4_global->proctable[node].slave_idx != 0)
  128.         continue;
  129.     ids[(*numids)++] = node;
  130.     }
  131. }
  132.  
  133.  
  134. P4VOID p4_get_cluster_ids(start, end)
  135. int *start;
  136. int *end;
  137. {
  138.  
  139.     *start = p4_global->low_cluster_id;
  140.     *end = p4_global->hi_cluster_id;
  141. }
  142.  
  143. /* This is used to figure out the local id of the calling process by
  144.  * indexing into the proctable until you find a hostname and a unix id
  145.  * that are the same as yours.
  146.  */
  147. int p4_get_my_id_from_proc()
  148. {
  149.     int i, my_unix_id;
  150.     struct proc_info *pi;
  151.     struct hostent *myhp, *pghp;
  152.  
  153. #   if (defined(IPSC860)  &&  !defined(IPSC860_SOCKETS))  ||  \
  154.        (defined(CM5)      &&  !defined(CM5_SOCKETS))      ||  \
  155.        (defined(NCUBE)    &&  !defined(NCUBE_SOCKETS))
  156.     return(MYNODE());
  157. #   else
  158.     my_unix_id = getpid();
  159.     if (p4_local->my_id == LISTENER_ID)
  160.     return (LISTENER_ID);
  161.     myhp = gethostbyname_p4(p4_global->my_host_name);
  162.  
  163.     for (pi = p4_global->proctable, i = 0; i < p4_global->num_in_proctable; i++, pi++)
  164.     {
  165.     if (pi->unix_id == my_unix_id)
  166.     {
  167.         if (strcmp(pi->host_name, p4_global->my_host_name) == 0)
  168.         {
  169.         return (i);
  170.         }
  171.         else
  172.         {
  173.         pghp = gethostbyname_p4(pi->host_name);
  174.         if (bcmp(myhp->h_addr, pghp->h_addr, myhp->h_length) == 0)
  175.         {
  176.             return (i);
  177.         }
  178.         }
  179.     }
  180.     }
  181.     p4_dprintf("process not in process table; my_unix_id = %d my_host=%s\n",
  182.            getpid(), p4_global->my_host_name);
  183.     p4_dprintf("Probable cause:  local slave on uniprocessor without shared memory\n");
  184.     p4_dprintf("Probable fix:  ensure only one process on %s\n",p4_global->my_host_name);
  185.     p4_dprintf("(on master process this means 'local 0' in the procgroup file)\n");
  186.     p4_dprintf("You can also remake p4 with SYSV_IPC set in the OPTIONS file\n");
  187.     p4_error("p4_get_my_id_from_proc",0);
  188. #   endif
  189. }
  190.  
  191. int p4_get_my_id()
  192. {
  193.     return (p4_local->my_id);
  194. }
  195.  
  196. int p4_get_my_cluster_id()
  197. {
  198. #   if (defined(IPSC860)  &&  !defined(IPSC860_SOCKETS))  ||  \
  199.        (defined(CM5)      &&  !defined(CM5_SOCKETS))      ||  \
  200.        (defined(NCUBE)    &&  !defined(NCUBE_SOCKETS))
  201.     return(MYNODE());
  202. #   else
  203.     if (p4_local->my_id == LISTENER_ID)
  204.     return (LISTENER_ID);
  205.     else
  206.     return (p4_global->proctable[p4_local->my_id].slave_idx);
  207. #   endif
  208. }
  209.  
  210. P4BOOL p4_am_i_cluster_master()
  211. {
  212.     if (p4_local->my_id == LISTENER_ID)
  213.     return (0);
  214.     else
  215.     return (p4_global->proctable[p4_local->my_id].slave_idx == 0);
  216. }
  217.  
  218. P4BOOL in_same_cluster(i, j)
  219. int i, j;
  220. {
  221.     return (p4_global->proctable[i].group_id ==
  222.         p4_global->proctable[j].group_id);
  223. }
  224.  
  225. P4VOID p4_cluster_shmem_sync(cluster_shmem)
  226. P4VOID **cluster_shmem;
  227. {
  228.     int myid = p4_get_my_cluster_id();
  229.  
  230.     if (myid == 0)  /* cluster master */
  231.     p4_global->cluster_shmem = *cluster_shmem;
  232.     p4_barrier(&(p4_global->cluster_barrier),p4_num_cluster_ids());
  233.     if (myid != 0)
  234.     *cluster_shmem = p4_global->cluster_shmem;
  235. }
  236.  
  237. #if defined(USE_XX_SHMALLOC)
  238. /* This is not machine dependent code but is only used on some machines */
  239.  
  240. /*
  241.   Memory management routines from ANSI K&R C, modified to manage
  242.   a single block of shared memory.
  243.   Have stripped out all the usage monitoring to keep it simple.
  244.  
  245.   To initialize a piece of shared memory:
  246.     xx_init_shmalloc(char *memory, unsigned nbytes)
  247.  
  248.   Then call xx_shmalloc() and xx_shfree() as usual.
  249. */
  250.  
  251. #define LOG_ALIGN 4
  252. #define ALIGNMENT (1 << LOG_ALIGN)
  253.  
  254. /* ALIGNMENT is assumed below to be bigger than sizeof(p4_lock_t) +
  255.    sizeof(Header *), so do not reduce LOG_ALIGN below 4 */
  256.  
  257. union header
  258. {
  259.     struct
  260.     {
  261.     union header *ptr;    /* next block if on free list */
  262.     unsigned size;        /* size of this block */
  263.     } s;
  264.     char align[ALIGNMENT];    /* Align to ALIGNMENT byte boundary */
  265. };
  266.  
  267. typedef union header Header;
  268.  
  269. static Header **freep;        /* pointer to pointer to start of free list */
  270. static p4_lock_t *shmem_lock;    /* Pointer to lock */
  271.  
  272. P4VOID xx_init_shmalloc(memory, nbytes)
  273. char *memory;
  274. unsigned nbytes;
  275. /*
  276.   memory points to a region of shared memory nbytes long.
  277.   initialize the data structures needed to manage this memory
  278. */
  279. {
  280.     int nunits = nbytes >> LOG_ALIGN;
  281.     Header *region = (Header *) memory;
  282.  
  283.     /* Quick check that things are OK */
  284.  
  285.     if (ALIGNMENT != sizeof(Header) ||
  286.     ALIGNMENT < (sizeof(Header *) + sizeof(p4_lock_t)))
  287.     p4_error("xx_init_shmem: Alignment is wrong", ALIGNMENT);
  288.  
  289.     if (!region)
  290.     p4_error("xx_init_shmem: Passed null pointer", 0);
  291.  
  292.     if (nunits < 2)
  293.     p4_error("xx_init_shmem: Initial region is ridiculously small",
  294.          (int) nbytes);
  295.  
  296.     /*
  297.      * Shared memory region is structured as follows
  298.      * 
  299.      * 1) (Header *) freep ... free list pointer 2) (p4_lock_t) shmem_lock ...
  300.      * space to hold lock 3) padding up to alignment boundary 4) First header
  301.      * of free list
  302.      */
  303.  
  304.     freep = (Header **) region;    /* Free space pointer in first block  */
  305.     shmem_lock = (p4_lock_t *) (freep + 1);    /* Lock still in first block */
  306.     (region + 1)->s.ptr = *freep = region + 1;    /* Data in rest */
  307.     (region + 1)->s.size = nunits - 1;    /* One header consumed already */
  308.  
  309. #   ifdef SYSV_IPC
  310.     shmem_lock->semid = sysv_semid0;
  311.     shmem_lock->semnum = 0;
  312. #   else
  313.     p4_lock_init(shmem_lock);                /* Initialize the lock */
  314. #   endif
  315.  
  316. }
  317.  
  318. char *xx_shmalloc(nbytes)
  319. unsigned nbytes;
  320. {
  321.     Header *p, *prevp;
  322.     char *address = (char *) NULL;
  323.     unsigned nunits;
  324.  
  325.     /* Force entire routine to be single threaded */
  326.     (P4VOID) p4_lock(shmem_lock);
  327.  
  328.     nunits = ((nbytes + sizeof(Header) - 1) >> LOG_ALIGN) + 1;
  329.  
  330.     prevp = *freep;
  331.     for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr)
  332.     {
  333.     if (p->s.size >= nunits)
  334.     {            /* Big enuf */
  335.         if (p->s.size == nunits)    /* exact fit */
  336.         prevp->s.ptr = p->s.ptr;
  337.         else
  338.         {            /* allocate tail end */
  339.         p->s.size -= nunits;
  340.         p += p->s.size;
  341.         p->s.size = nunits;
  342.         }
  343.         *freep = prevp;
  344.         address = (char *) (p + 1);
  345.         break;
  346.     }
  347.     if (p == *freep)
  348.     {            /* wrapped around the free list ... no fit
  349.                  * found */
  350.         address = (char *) NULL;
  351.         break;
  352.     }
  353.     }
  354.  
  355.     /* End critical region */
  356.     (P4VOID) p4_unlock(shmem_lock);
  357.  
  358.     if (address == NULL)
  359.     p4_dprintf("xx_shmalloc: returning NULL; requested %d bytes\n",nbytes);
  360.     return address;
  361. }
  362.  
  363. P4VOID xx_shfree(ap)
  364. char *ap;
  365. {
  366.     Header *bp, *p;
  367.  
  368.     /* Begin critical region */
  369.     (P4VOID) p4_lock(shmem_lock);
  370.  
  371.     if (!ap)
  372.     return;            /* Do nothing with NULL pointers */
  373.  
  374.     bp = (Header *) ap - 1;    /* Point to block header */
  375.  
  376.     for (p = *freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr)
  377.     if (p >= p->s.ptr && (bp > p || bp < p->s.ptr))
  378.         break;        /* Freed block at start of end of arena */
  379.  
  380.     if (bp + bp->s.size == p->s.ptr)
  381.     {                /* join to upper neighbour */
  382.     bp->s.size += p->s.ptr->s.size;
  383.     bp->s.ptr = p->s.ptr->s.ptr;
  384.     }
  385.     else
  386.     bp->s.ptr = p->s.ptr;
  387.  
  388.     if (p + p->s.size == bp)
  389.     {                /* Join to lower neighbour */
  390.     p->s.size += bp->s.size;
  391.     p->s.ptr = bp->s.ptr;
  392.     }
  393.     else
  394.     p->s.ptr = bp;
  395.  
  396.     *freep = p;
  397.  
  398.     /* End critical region */
  399.     (P4VOID) p4_unlock(shmem_lock);
  400. }
  401. #endif
  402.  
  403. P4VOID get_pipe(end_1, end_2)
  404. int *end_1;
  405. int *end_2;
  406. {
  407.     int p[2];
  408.  
  409. #   if defined(IPSC860)  ||  defined(CM5)  ||  defined(NCUBE)
  410.     p4_dprintf("WARNING: get_pipe: socketpair assumed unavailable on this machine\n");
  411.     return;
  412. #   else
  413.     if (socketpair(AF_UNIX, SOCK_STREAM, 0, p) < 0)
  414.     p4_error("get_pipe: socketpair failed ", -1);
  415.     *end_1 = p[0];
  416.     *end_2 = p[1];
  417. #   endif
  418. }
  419.  
  420. P4VOID setup_conntab()
  421. {
  422.     int i, my_id;
  423.  
  424.     p4_dprintfl(60, "setup_conntab: myid=%d, switch_port=%d, app_id=%s\n",
  425.         p4_local->my_id,
  426.         p4_global->proctable[p4_local->my_id].switch_port,
  427.         p4_global->application_id);
  428.     p4_local->conntab = (struct connection *)
  429.     p4_malloc(p4_global->num_in_proctable * sizeof(struct connection));
  430.     my_id = p4_get_my_id();
  431.  
  432.     for (i = 0; i < p4_global->num_in_proctable; i++)
  433.     {
  434.     if (i == my_id)
  435.     {
  436.         p4_local->conntab[i].type = CONN_ME;
  437.         p4_local->conntab[i].port = 0;
  438.     }
  439.     else if (in_same_cluster(i, my_id))
  440.     {
  441.         p4_local->conntab[i].type = CONN_LOCAL;
  442. #           if defined(IPSC860) || defined(CM5)  ||  defined(NCUBE)
  443.         p4_local->conntab[i].port = MYNODE() + i - p4_local->my_id;
  444. #           endif
  445. #           if defined(TCMP)
  446.         p4_local->conntab[i].port = i - p4_global->low_cluster_id;
  447. #           endif
  448.     }
  449.     else if ((p4_global->proctable[my_id].switch_port != -1) &&
  450.          (p4_global->proctable[i].switch_port != -1) &&
  451.          (p4_global->proctable[my_id].switch_port !=
  452.           p4_global->proctable[i].switch_port))
  453.     {
  454.         p4_local->conntab[i].type = CONN_REMOTE_SWITCH;
  455.         p4_local->conntab[i].switch_port = p4_global->proctable[i].switch_port;
  456.     }
  457.     else
  458.     {
  459.         p4_local->conntab[i].type = CONN_REMOTE_NON_EST;
  460.         p4_local->conntab[i].port = p4_global->proctable[i].port;
  461.     }
  462.     }
  463.     p4_dprintfl(60, "conntab after setup_conntab:\n");
  464.     dump_conntab(60);
  465. }
  466.  
  467. #ifdef SYSV_IPC
  468. P4VOID remove_sysv_ipc()
  469. {
  470.     int i;
  471.     struct p4_global_data *g = p4_global;
  472.  
  473.     /* ignore -1 return codes below due to multiple processes cleaning
  474.        up the same sysv stuff; commented out "if" used to make sure
  475.        that only the cluster master cleaned up in each cluster
  476.     */
  477.     /* if (p4_local != NULL  &&  p4_get_my_cluster_id() != 0) return; */
  478.  
  479.     semctl(g->sysv_semid[0],0,IPC_RMID,0);  /* delete initial set */
  480.     if (sysv_shmid[0] == -1)
  481.     return;
  482.     for (i=0; i < sysv_num_shmids; i++)
  483.         shmctl(sysv_shmid[i],IPC_RMID,0);
  484.     if (g == NULL)
  485.         return;
  486.     for (i=1; i < g->sysv_num_semids; i++)  /* delete other sets */
  487.     {
  488.     semctl(g->sysv_semid[i],0,IPC_RMID,0);
  489.     }
  490. }
  491. #endif
  492.  
  493. int p4_wait_for_end()
  494. {
  495.     int status;
  496.     int i, n_forked_slaves, pid;
  497.     struct slave_listener_msg msg;
  498.  
  499.     ALOG_LOG(p4_local->my_id,END_USER,0,"");
  500.     ALOG_OUTPUT;
  501.     if (p4_get_my_cluster_id() != 0)
  502.     return;
  503.  
  504.     /* Wait for all forked processes except listener to die */
  505.     p4_dprintfl(90, "enter wait_for_end nfpid=%d\n",p4_global->n_forked_pids);
  506.     if (p4_local->listener_fd == (-1))
  507.         n_forked_slaves = p4_global->n_forked_pids;
  508.     else
  509.         n_forked_slaves = p4_global->n_forked_pids - 1;
  510.     for (i = 0; i < n_forked_slaves; i++)
  511.     {
  512.     pid = wait(&status);
  513.     p4_dprintfl(90, "detected that proc %d died \n", pid);
  514.     }
  515.  
  516. #   ifdef CAN_DO_SOCKET_MSGS
  517.     /* Tell the listener to die and wait for him to do so */
  518.     if (p4_local->listener_fd != (-1))
  519.     {
  520.     p4_dprintfl(90, "tell listener to die listpid=%d fd=%d\n",
  521.             p4_global->listener_pid, p4_local->listener_fd);
  522.     msg.type = p4_i_to_n(DIE);
  523.     msg.from = p4_i_to_n(p4_get_my_id());
  524.     net_send(p4_local->listener_fd, &msg, sizeof(msg), FALSE);
  525.     pid = wait(&status);
  526.     p4_dprintfl(90, "detected that proc %d died \n", pid);
  527.     }
  528. #   endif
  529.  
  530. #   ifdef SYSV_IPC
  531.     remove_sysv_ipc();
  532. #   endif
  533.  
  534.     if (p4_get_my_id())
  535.         p4_dprintfl(20,"process exiting\n");
  536.     p4_dprintfl(90, "exit wait_for_end \n");
  537.     return (0);
  538. }
  539.  
  540.  
  541. /* static variables private to fork_p4 and zap_p4_processes */
  542. static int n_pids = 0;
  543. static int pid_list[P4_MAXPROCS];
  544.  
  545. int fork_p4()
  546. /*
  547.   Wrapper round fork for sole purpose of keeping track of pids so 
  548.   that can signal error conditions.  See zap_p4_processes.
  549. */
  550. {
  551.     int pid;
  552.  
  553. #   if defined(IPSC860)  ||  defined(CM5)  ||  defined(NCUBE)
  554.     p4_error("fork_p4: nodes cannot fork processes",0);    
  555. #   else
  556.     if (p4_global->n_forked_pids >= P4_MAXPROCS)
  557.     p4_error("forking too many local processes; max = ", P4_MAXPROCS);
  558.     p4_global->n_forked_pids++;
  559.  
  560.     fflush(stdout);
  561.     pid = fork();
  562.  
  563.     if (pid > 0)
  564.     {
  565.     /* Parent process */
  566.     pid_list[n_pids++] = pid;
  567.     }
  568.     else if (pid == 0)
  569.     {
  570.     /* Child process */
  571.     pid_list[n_pids++] = getppid();
  572.     }
  573.     else
  574.     p4_error("fork_p4: fork failed", pid);
  575. #   endif
  576.  
  577.     return pid;
  578. }
  579.  
  580. P4VOID zap_p4_processes()
  581. {
  582.     int n;
  583.     
  584.     if (p4_global == NULL)
  585.         return;
  586.     n = p4_global->n_forked_pids;
  587.     while (n--)
  588.     {
  589.     kill(pid_list[n], SIGINT);
  590.     }
  591. }
  592.  
  593. P4VOID get_qualified_hostname(str)
  594. char *str;
  595. {
  596. #   if (defined(IPSC860)  &&  !defined(IPSC860_SOCKETS))  ||  \
  597.        (defined(CM5)      &&  !defined(CM5_SOCKETS))      ||  \
  598.        (defined(NCUBE)    &&  !defined(NCUBE_SOCKETS))
  599.     strcpy(str,"cube_node");
  600. #else
  601.     if (*str == '\0')
  602.         gethostname(str, 100);
  603.     if (*local_domain != '\0'  &&  !index(str,'.'))
  604.     {
  605.     strcat(str,".");
  606.     strcat(str,local_domain);
  607.     }
  608. #endif
  609. }
  610.  
  611.  
  612. int getswport(hostname)
  613. char *hostname;
  614. {
  615.     char local_host[256];
  616.  
  617. #ifdef CAN_DO_SWITCH_MSGS
  618.     if (strcmp(hostname, "local") == 0)
  619.     {
  620.     local_host[0] = '\0';
  621.     get_qualified_hostname(local_host);
  622.     return getswport(local_host);
  623.     }
  624.     if (strcmp(hostname, "hurley") == 0)
  625.     return 1;
  626.     if (strcmp(hostname, "hurley.tcg.anl.gov") == 0)
  627.     return 1;
  628.     if (strcmp(hostname, "hurley.mcs.anl.gov") == 0)
  629.     return 1;
  630.     if (strcmp(hostname, "campus.mcs.anl.gov") == 0)
  631.     return 2;
  632.     if (strcmp(hostname,"mpp1") == 0)
  633.       return 3;
  634.     if (strcmp(hostname,"mpp2") == 0)
  635.       return 28;
  636.     if (strcmp(hostname,"mpp3") == 0)
  637.       return 6;
  638.     if (strcmp(hostname,"mpp4") == 0)
  639.       return 7;
  640.     if (strcmp(hostname,"mpp7") == 0)
  641.       return 14;
  642.     if (strcmp(hostname,"mpp8") == 0)
  643.       return 25;
  644.     if (strcmp(hostname,"mpp9") == 0)
  645.       return 20;
  646.     if (strcmp(hostname,"mpp10") == 0)
  647.       return 11;
  648. #endif
  649.  
  650.     return -1;
  651. }
  652.  
  653. P4BOOL same_data_representation(id1,id2)
  654. {
  655.     struct proc_info *p1 = &(p4_global->proctable[id1]);
  656.     struct proc_info *p2 = &(p4_global->proctable[id2]);
  657.  
  658.     return (data_representation(p1->machine_type) == data_representation(p2->machine_type));
  659. }
  660.